package com.example.partyfee.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.partyfee.dto.LoginDTO;
import com.example.partyfee.dto.LoginResponseDTO;
import com.example.partyfee.dto.UserDTO;
import com.example.partyfee.entity.User;
import com.example.partyfee.exception.BusinessException;
import com.example.partyfee.repository.UserRepository;
import com.example.partyfee.service.UserService;
import com.example.partyfee.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;

    @Override
    public LoginResponseDTO login(LoginDTO loginDTO) {
        User user = userRepository.selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getUsername, loginDTO.getUsername())
        );

        if (user == null || !passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        if (user.getStatus() == 0) {
            throw new BusinessException("账号已被禁用");
        }

        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        userRepository.updateById(user);

        // 生成token
        String token = jwtUtil.generateToken(user.getUsername());

        // 构建响应
        LoginResponseDTO response = new LoginResponseDTO();
        response.setToken(token);
        response.setUsername(user.getUsername());
        response.setRealName(user.getRealName());
        response.setRole(user.getRole());

        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUser(UserDTO userDTO) {
        // 检查用户名是否已存在
        if (userRepository.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, userDTO.getUsername())) > 0) {
            throw new BusinessException("用户名已存在");
        }

        User user = new User();
        user.setUsername(userDTO.getUsername());
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        user.setRealName(userDTO.getRealName());
        user.setRole(userDTO.getRole());
        user.setStatus(1);

        userRepository.insert(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(Long id, UserDTO userDTO) {
        User user = userRepository.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 如果修改了用户名，需要检查是否已存在
        if (!user.getUsername().equals(userDTO.getUsername()) &&
                userRepository.selectCount(new LambdaQueryWrapper<User>()
                        .eq(User::getUsername, userDTO.getUsername())) > 0) {
            throw new BusinessException("用户名已存在");
        }

        user.setUsername(userDTO.getUsername());
        user.setRealName(userDTO.getRealName());
        user.setRole(userDTO.getRole());

        userRepository.updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long id) {
        if (userRepository.deleteById(id) == 0) {
            throw new BusinessException("用户不存在");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        User user = userRepository.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new BusinessException("原密码错误");
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.updateById(user);
    }
} 